package my.algo.sort;

import java.util.Arrays;

/**
 * 堆排序：构建一个父节点大于所有子节点的完全二叉树。
 */
public class Heap {

	public static void sort(int[] arr) {
        // 1.构建大顶堆 O(N*logN)
//        for (int i = 0; i < arr.length; i++) {
//            heapInert(arr, i);
//        }
        // 1.构建大顶堆(优化)O(N)
        for (int i = arr.length/2-1; i>=0; i--) {
            //从第一个非叶子结点从下至上，从右至左调整结构
            adjustHeap(arr, i, arr.length);
        }
		print(arr);
        // 2.调整堆结构+交换堆顶元素与末尾元素
        for (int j = arr.length-1; j>0; j--) {
			System.out.print(arr[0] + " ");
            exchange(arr, 0, j);
            adjustHeap(arr, 0, j);
        }
    }

    /**
     * 调整大顶堆（仅是调整过程，建立在大顶堆已构建的基础上）
     */
    public static void adjustHeap(int[] arr, int i, int length) {
        int temp = arr[i];
        for (int k = i*2+1; k < length; k = k*2+1) {
            if (k+1 < length && arr[k] < arr[k+1]) {
                k++;
            }
            if (arr[k] > temp) {
                arr[i] = arr[k];
                i = k;
            } else {
                break;
            }
        }
        arr[i] = temp;
    }

    private static void exchange(int[] a, int i, int j) {
        int t = a[i];
        a[i] = a[j];
        a[j] = t;
    }

	private static void print(int[] arr) {
		System.out.println(Arrays.toString(arr));
	}

	public static void main(String[] args) {
		int[] a = {50, 30, 60, 90, 40, 21, 54, 44, 32};
		sort(a);
		print(a);
	}
}
